package jvm;

/**
 * 可以看下面博客
 * https://blog.csdn.net/u010798968/article/details/72835255
 * 在java中,可视为GCRoot的对象有
 * 1. 虚拟机栈中引用的对象;
 * 2. 方法区中的类静态属性引用的对象  private static GcRootDemo root;  不会回收
 * 3. 方法区中常量引用的对象  private static final GcRootDemo root = new GcRootDemo() 不会回收
 * 4. 本地方法jni(java native interface) 即native方法中引用的对象
 *
 * 方法区是线程共享的，通常用来保存装载的类的元结构信息。
 * 比如：运行时常量池+静态变量+常量+字段+方法字节码+在类/实例/接口初始化用到的特殊方法等。
 *
 * @author jiangwz
 * @create 2019/9/16.
 */
public class GcRootDemo {

    /**
     * [GC (System.gc()) [PSYoungGen: 3686K->664K(38400K)] 3686K->672K(125952K), 0.0016607 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
     * [Full GC (System.gc()) [PSYoungGen: 664K->0K(38400K)] [ParOldGen: 8K->537K(87552K)] 672K->537K(125952K), [Metaspace: 2754K->2754K(1056768K)], 0.0059024 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
     * Heap
     *  PSYoungGen      total 38400K, used 333K [0x00000000d5c00000, 0x00000000d8680000, 0x0000000100000000)
     *   eden space 33280K, 1% used [0x00000000d5c00000,0x00000000d5c534a8,0x00000000d7c80000)
     *   from space 5120K, 0% used [0x00000000d7c80000,0x00000000d7c80000,0x00000000d8180000)
     *   to   space 5120K, 0% used [0x00000000d8180000,0x00000000d8180000,0x00000000d8680000)
     *  ParOldGen       total 87552K, used 537K [0x0000000081400000, 0x0000000086980000, 0x00000000d5c00000)
     *   object space 87552K, 0% used [0x0000000081400000,0x00000000814864a0,0x0000000086980000)
     *  Metaspace       used 2761K, capacity 4486K, committed 4864K, reserved 1056768K
     *   class space    used 299K, capacity 386K, committed 512K, reserved 1048576K
     *
     * GC日志开头的”[GC”和”[Full GC”说明了这次垃圾收集的停顿类型，如果有”Full”，说明这次GC发生了”Stop-The-World”。因为是调用了System.gc()方法触发的收集，所以会显示”[Full GC (System.gc())”，不然是没有后面的(System.gc())的。
     *
     * “[PSYoungGen”和”[ParOldGen”是指GC发生的区域，分别代表使用Parallel Scavenge垃圾收集器的新生代和使用Parallel old垃圾收集器的老生代。为什么是这两个垃圾收集器组合呢？因为我的jvm开启的模式是Server，而Server模式的默认垃圾收集器组合便是这个，在命令行输入java -version就可以看到自己的jvm默认开启模式。还有一种是client模式，默认组合是Serial收集器和Serial Old收集器组合。
     *
     * 在方括号中”PSYoungGen:”后面的”3686K->664K(38400K)”代表的是”GC前该内存区域已使用的容量->GC后该内存区域已使用的容量(该内存区域总容量)”
     *
     * 在方括号之外的”3686K->672K(125952K)”代表的是”GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)”
     *
     * 再往后的”0.0016607 sec”代表该内存区域GC所占用的时间，单位是秒。
     *
     * 再后面的”[Times: user=0.00 sys=0.00, real=0.00 secs]”，user代表进程在用户态消耗的CPU时间，sys代表代表进程在内核态消耗的CPU时间、real代表程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间（比如等待 I/O 完成）。
     *
     * 至于后面的”eden”代表的是Eden空间，还有”from”和”to”代表的是Survivor空间。
     */



    // final关键字修饰
    private int MAX_BYTE = 1024 * 1024; //
    private byte[] byteArray = new byte[MAX_BYTE];

    /**
     * -Xms10m -Xmx10m -Xmn5m  -XX:+PrintGCDetails
     *  PSYoungGen = 年轻代垃圾收集器    [PSYoungGen: 3749K->488K(4608K)]  gc前年轻代 3749K,gc后488K,总的4608K. 3749K->1949K(9728K) 表示GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
     * [GC (System.gc()) [PSYoungGen: 3749K->488K(4608K)] 3749K->1949K(9728K), 0.0025002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
     * [Full GC (System.gc()) [PSYoungGen: 488K->0K(4608K)] [ParOldGen: 1461K->1913K(5120K)] 1949K->1913K(9728K), [Metaspace: 3283K->3283K(1056768K)], 0.0044118 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
     * 第一次GC完成
     * [GC (System.gc()) [PSYoungGen: 75K->64K(4608K)] 1989K->1977K(9728K), 0.0002380 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
     * [Full GC (System.gc()) [PSYoungGen: 64K->0K(4608K)] [ParOldGen: 1913K->770K(5120K)] 1977K->770K(9728K), [Metaspace: 3284K->3284K(1056768K)], 0.0043948 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
     * 第二次GC完成
     * Heap
     *  PSYoungGen      total 4608K, used 158K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
     *   eden space 4096K, 3% used [0x00000000ffb00000,0x00000000ffb27880,0x00000000fff00000)
     *   from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
     *   to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
     *  ParOldGen       total 5120K, used 770K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
     *   object space 5120K, 15% used [0x00000000ff600000,0x00000000ff6c08b8,0x00000000ffb00000)
     *  Metaspace       used 3291K, capacity 4496K, committed 4864K, reserved 1056768K
     *   class space    used 357K, capacity 388K, committed 512K, reserved 1048576K
     */

    /**
     * GCROOT对象 GcRootDemo()在虚拟机栈中所以不会被回收
     * 虚拟机栈中引用的对象;
     * -Xms10m -Xmx10m -Xmn5m  -XX:+PrintGCDetails
     * 初始堆内存  最大堆内存
     */
    public static void m1(){
        GcRootDemo ti = new GcRootDemo(); // new GcRootDemo() ->GCRoot
        System.gc();
        System.out.println("第一次GC完成");
    }

    public static void main(String[] args) {
        // 测试 虚拟机栈中引用的对象;
        m1();
        System.gc();
        System.out.println("第二次GC完成");

    }



}
